/**
 * <p>文件名:		BinaryJedisCluster.java</p>
 * <p>版权:		CopyrightTag</p>
 * <p>公司:		CompanyTag</p>
 * @author		周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 */

package com.caits.lbs.framework.services.redis;

import java.util.Set;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisClusterCommand;
import redis.clients.jedis.JedisPubSub;
import redis.clients.util.SafeEncoder;

/**
 * <p>
 * BinaryJedisCluster
 * </p>
 * <p>
 * 二进制jedis集群客户端类
 * </p>
 *
 * @author 周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>zhouhuabin</td>
 *          <td>2015年4月22日 下午5:48:48</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public class MyJedisCluster extends JedisCluster {

	/**
	 * 构造器
	 * 
	 * @param jedisClusterNode
	 * @param password
	 * @param timeout
	 * @param maxRedirections
	 * @param poolConfig
	 */
	public MyJedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections, GenericObjectPoolConfig poolConfig, String password) {
		super(jedisClusterNode, timeout, maxRedirections, poolConfig, password);
	}

	@Override
	public Long linsert(final byte[] key, final LIST_POSITION where, final byte[] pivot, final byte[] value) {
		JedisClusterCommand<Long> runner = new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
			public Long execute(final Jedis connection) {
				return connection.linsert(key, where, pivot, value);
			}
		};
		return runner.runBinary(key);
	}

	/**
	 * 消息收发在cluster模式下支持,所以添加
	 * FIXME 
	 * @param channel
	 * @param message
	 * @return
	 */
	public Long publish(final String channel, final String message) {
		JedisClusterCommand<Long> runner = new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
			public Long execute(final Jedis connection) {
				return connection.publish(channel, message);
			}
		};
		return runner.runBinary(SafeEncoder.encode(channel));
	}
	/**
	 * 订阅多个channel的消息 
	 * @param jedisPubSub
	 * @param channels
	 */
	public void subscribe(final JedisPubSub jedisPubSub, final String... channels) {
		JedisClusterCommand<Long> runner = new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
			public Long execute(final Jedis connection) {
				connection.subscribe(jedisPubSub, channels);
				return Long.valueOf(channels.length);
			}
		};
		runner.runWithAnyNode();
	}
	/**
	 * 
	 * 订阅多个pattern的消息 
	 * @param jedisPubSub
	 * @param patterns
	 */
	public void psubscribe(final JedisPubSub jedisPubSub, final String... patterns) {
		JedisClusterCommand<Long> runner = new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {
			public Long execute(final Jedis connection) {
				connection.psubscribe(jedisPubSub, patterns);
				return Long.valueOf(patterns.length);
			}
		};
		runner.runWithAnyNode();
	}

	public String randomKey() {
		JedisClusterCommand<String> runner = new JedisClusterCommand<String>(connectionHandler, maxRedirections) {
			public String execute(final Jedis connection) {
				return connection.randomKey();
			}
		};
		return runner.runWithAnyNode();
	}
	/**
	 * 后面的接口集群模式下尽量少用,会导致 (error) CROSSSLOT Keys in request don't hash to the
	 * same slot<br>
	 * 多个key可能不在同一个node下,操作会失败<br>
	 * 需要处理多个键的命令是不能在集群里面执行的。
	 */
}
